<template>
  <div class="el-form-item__content" style="margin-left: 0px;" >    
    <pre>
        1,component 标签的 is属性,不要使用字符串(避免需要声明),改为使用组件内容(在mount事件中通过异步获得),
        <br />
        参考:https://cn.vuejs.org/v2/guide/components.html#%E5%8A%A8%E6%80%81%E7%BB%84%E4%BB%B6
        <br />
        2,包含el-table的组件中不要使用异步组件声明子组件,el-table在根据data内容进行渲染的同时,才会开始异步载入组件,导致渲染失败,
        如果手动执行el-table.doLayout(),会发现内容正常显示了.
        <br />改为在mount事件中进行异步批量载入 
        <br />require([],function(...){改变表单项配置中的content属性，并dolayout});       
        <br />同时动态组件 component 的 is属性，不要使用字符串，改为使用content,
        <br />以上代码中，mount事件中异步载入子组件代码后,调用el-table.doLayout(),重新渲染表格,
        <br />
        4,这个问题只对el-table出现,动态组件如果不用在el-table中,不会发生,可能是el-table的bug,优化el-table的代码 to do
        <br />
        如果组件中没有使用el-table,可以正常使用异步组件声明.
        <br />
        5,其他思路: <br/>类似于elment,索性全部一次性载入
        <br />
        凡是组件中调用了el-table的，调用vue.componet('',{})前对需要的子组件进行预载入，改变配置项的组件注册参数,类似_tablelist.js的做法
        6,以上场景同样适用于 comp-table,和 comp-advsearch-dialog中,可用相同方法进行优化.
      </pre>
    <template>

      <button @click="handleTest">dolayout</button>
      <el-table
        :data="row[fld.key]"
        size="mini"
        style="width: 100%"
        ref="tbl">
        <el-table-column
          v-for="(_item,_k) in sonItems.items"
          :key="_k"
          :label="_item.title"
          :width="_item.width||150">

          <template slot-scope="scope">
            <!-- 注意下面的is属性写法,不能是字符串 -->
            <component
              :is="_item.content"
              :fld="_item"
              :value="isset(scope.row,_item.name) ? scope.row[_item.name] : _item.value"
              @input="handleSonInput(scope.row,_item.name,arguments[0])"
              :row="scope.row"
              :ref="'son_'+_item.name+'_'+scope.$index"
            ></component>
          </template>
        </el-table-column>
      </el-table>
    </template>
  </div>

 
</template>
<script>
  //使用非懒载入，没有问题，如下
  // define(['vue','Common','_vue!pathComponent/comp-text','_vue!pathComponent/comp-select'],function(vue,Common){
  //在mounted中，延迟300ms，执行 dolayout()没有问题
  //不再el-table中，没有问题
  define(['vue','Common'],function(vue,Common){
  // define(['vue','Common','_vue!pathComponent/comp-text','_vue!pathComponent/comp-test'],function(vue,Common,a,b){
    return vue.component('comp-head-select',{
      template:template,
      // components:{'comp-text':a,},
      // inject: [ "_VueRoot_" ],
      // name : 'comp-head-select',
      //方式一：
      // components : {
      //   'comp-text': resolve=>require(['_vue!pathComponent/comp-text'], resolve),
      //   'comp-test': resolve=>require(['_vue!pathComponent/comp-test'], resolve),
      // },

      //方式二：
      // components:{
      //   'comp-text' : (resolve)=>{
      //     require(['_vue!pathComponent/comp-text'], function(a){
      //       resolve(arguments[0]);
      //     });
      //   },
      //   'comp-test' : (resolve)=>{
      //     require(['_vue!pathComponent/comp-test'], function(a){
      //       resolve(arguments[0]);
      //     });
      //   },
      // },

      //方式叁,声明后立即执行函数
      // components : ((resolve) =>{ 
      //   var comps = ['comp-text','comp-test'];
      //   var ret = {};
      //   for(var c of comps) {
      //     ret[c] = (resolve)=>{
      //       require([`_vue!pathComponent/${c}`], function(a){
      //         // window.__this.$refs.tbl.doLayout();
      //         dump('import end');
      //         resolve(a);
      //       });
      //     }
      //   }
      //   return ret
      // })(),

      props : {
        fld :{required:false,default:{'alertType':'info','alertTitle':'我是标题.alertTitle','sonItems':{},'key':''}},
        value :{required:false,default:function(){
          if(this.fld.multiple) return [];
          return '';
        }},
        row:{required:false,default:[]}
      },
      data : function(){
        return {
          'type' : this.fld.alertType ? this.fld.alertType : 'info',
          'sonKey' : this.fld.name ? this.fld.name : '',
          'sonItems' : this.fld.sonItems ? this.fld.sonItems : '',
        };
      },
      methods:{
        handleTest:function() {
          var temp=[];
          temp[0]  = this.row.qclArr[1];
          temp[1]  = this.row.qclArr[0];
          this.row.qclArr = temp;
          // debugger;
          // this.$refs.tbl.doLayout();
        },
        isset : Common.isset,
        //字表记录中的组件值改变触发改变字表记录
        handleSonInput : function(row,key,val) {
          dump({row},{key},{val});
          if(Common.isset(row,key)) {
            row[key] = val;
          } else {
            vue.set(row,key,val);
          }
        },
        getDisplayText : function(val) {
          if(!val) val = this.value;
          //根据option和value设置displayText,回显时需要用到
          var displayText='';
          if(!this.fld.multiple) {
            for(var i=0;this.fld.options[i];i++) {
              if(this.fld.options[i].value==val) {
                displayText = this.fld.options[i].text;
                break;
              }
            }
          } else {
            var temp = [];
            for(var j=0;val[j];j++) {
              for(var i=0;this.fld.options[i];i++) {
                if(this.fld.options[i].value==val[j]) {
                  temp.push(this.fld.options[i].text);
                }
              }
            }
            displayText = temp.join(',');
          }
          return displayText;
        },
        handleModelInput :function(val){
          this.$emit("input", val);
          this.displayText = this.getDisplayText(val);
          //向总线提交事件，在mainson弹窗中，如果存在select控件，需要通过总线，改变cureentRow中的某个字段的值，用来显示在字表中
          //比如在弹框中选择了客户后，clientId改变的同时，必须在字表中显示对应客户的compName字段
          //构造需要传递的option
          var newVal = [];
          if(typeof(val)=='object') newVal = val;
          else newVal.push(val);
          var opt = [];
          for (var i=0;this.fld.options[i];i++) {
            var v = this.fld.options[i].value;
            if(newVal.indexOf(v)==-1) continue;
            opt.push(this.fld.options[i]);
          }
          this.$bus.$emit('selectChanged',this.fld.name,opt);
        },
        handleChange : function(item) {
          this.$emit("change", item,this);
          var key = `${this.fld.name}:change`;
          if(!this.$root.callbacks[key]) return;
          this.$root.callbacks[key].apply(this,arguments);
        }
      },
      mounted: function() {
        dump('head-select mounted,itmes:',this.sonItems.items);
        var items = this.sonItems.items;
        var that = this;
        //异步载入,可以根据 this.sonItems.items 动态载入,这里就不改造了,可以参考comp-table.mounted代码
        require([`_vue!pathComponent/comp-text`,`_vue!pathComponent/comp-test`],function(a,b){      
          items.colorNum.content = a;      
          items.memo.content = b;  
          console.log('import over');    
          //如果在el-table使用自定义组件,会渲染失败,可能是el-table的bug,所以这里要重新渲染下
          that.$refs.tbl.doLayout();
        });
      },
      // created: function() {
      //   // dump('row',this.row.qclArr  );
      //   dump('head-select created');
      // }
    });
  });
</script>
<style>
.el-alert__content{float: left;    }
.el-alert__description{float:right;}
.el-alert__title{padding-top: 5px;height: 26px;line-height: 26px;}
.el-alert__right{float: right;padding-left: 10px;}
.el-alert__title {
    vertical-align: middle;
    float: left;
    font-size: 10px;
    color: #606266;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width:70px;
}
</style>
